package main

//同时导入多个包
//导入的包必须使用，否则报错
import (
	"fmt"
	//如果导入某个包，但是不使用它，可以使用下划线_标注
	//_ "math"
	"math"
	"io/ioutil"    //io相关
	"math/cmplx"   //复数相关
)

//定义函数
//函数定义方式为:func 函数名 (函数参数) 函数返回值 {
//{左大括号不能向C语言那样单独占据一行
func euler() {
	//复数
	complexValue := 3 + 4i
	fmt.Println(cmplx.Abs(complexValue))
	//计算e^(i*Pi)+1的值
	//为了让编译器将i理解为虚部，需要写成1i
	fmt.Println(cmplx.Pow(math.E, 1i*math.Pi) + 1)
	fmt.Printf("%.2f\n", cmplx.Exp(1i*math.Pi)+1)
}

//go语言不存在任何隐式类型转换
//所有类型转换都必须是强制的
func strongType() {
	fmt.Println("进入strongType函数")
	var a, b int = 3, 4
	var c int
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println("c =", c)
	fmt.Println("退出strongType函数")
}
	
//go语言的枚举类型通常使用const和iota来实现
func enumType() {
	const (
		//使用iota时，后续常量或变量会自动套用公式
		enum1 = 1 << iota
		enum2
		enum3
		enum4
		enum5
	)
	println(enum1, enum2, enum3, enum4, enum5)
}
	
	//文件相关
	//if的用法
	func fileIO() {
		const fileName = "file.txt"
		//打开文件
		//ReadFile函数需要在文件存在的前提下才能成功
		contents, err := ioutil.ReadFile(fileName)
		//if后面的判断不需要添加括号
		//如果if语句里定义了新的变量，那么该变量只能在if块内使用
		if err != nil {
			fmt.Println("open", fileName, "failed:", err)
			//else不能单独启一行，必须放在}和{之间
		} else {
			fmt.Printf("%s\n", contents)
		}
	}
	
	//switch的用法
	func eval(a, b int, op string) int {
		switch op {
		case "+":
			return a + b
		case "-":
			return a - b
		case "*":
			return a * b
		case "/":
			return a / b
		default:
			//报错
			panic(op + "not leagle")
		}
	}
	
	//switch的另一种用法
	func useSwitch() {
		score := 77
		ju := ""
		switch {
		case score < 60 && score >= 0:
			ju = "差"
		case score < 80:
			ju = "中"
		case score < 90:
			ju = "良"
		case score <= 100:
			ju = "优"
		default:
			panic(fmt.Sprintf("score %d not in [0,100]", score))
		}
		fmt.Println(ju)
	}
	